package com.start.oss.controller;

import cn.hutool.core.io.IoUtil;
import com.start.common.api.Result;
import com.start.common.exceptions.StartResourceNotFoundException;
import com.start.common.tools.SpringContextTools;
import com.start.oss.OssAccessType;
import com.start.oss.StartOssData;
import com.start.oss.StartOssService;
import com.start.oss.ext.ByteMultipartFile;
import com.start.security.annotations.StartUrlDataSecurity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@RequestMapping({"start/oss/resource"})
@RestController
public class StartResourceController {
    @Autowired
    private StartOssService startOssService;


    @PostMapping("/formUpload")
    public Result<?> formUpload(@RequestParam(value = "file", required = false) MultipartFile file,
                                @RequestParam(value = "accessType", defaultValue = "public") OssAccessType accessType,
                                String storageType,
                                @RequestParam(value = "hexName", defaultValue = "true") boolean hexName) {
        final StartOssData startOssData = new StartOssData(file);
        startOssData.setAccessType(accessType);
        startOssData.setOssStorageType(storageType);
        startOssData.setAutoRename(hexName);
        return Result.ok(startOssService.add(startOssData));
    }


    @PostMapping("/base64Upload")
    public Result<?> base64Upload(@RequestBody String baseStr,
                                  @RequestParam(value = "accessType", defaultValue = "public") OssAccessType accessType,
                                  String fileName,
                                  String storageType,
                                  @RequestParam(value = "hexName", defaultValue = "true") boolean hexName) {
        final MultipartFile multipartFile = ByteMultipartFile.base64ToMultipart(baseStr, fileName);
        final StartOssData startOssData = new StartOssData(multipartFile);
        startOssData.setAccessType(accessType);
        startOssData.setOssStorageType(storageType);
        startOssData.setAutoRename(hexName);
        return Result.ok(startOssService.add(startOssData));
    }


    @PostMapping("/postUpload")
    public Result<?> postUpload(@RequestBody byte[] bytes,
                                @RequestParam(value = "accessType", defaultValue = "public") OssAccessType accessType,
                                String fileName,
                                String storageType,
                                @RequestParam(value = "hexName", defaultValue = "true") boolean hexName) {
        final MultipartFile multipartFile = ByteMultipartFile.byteToMultipart(bytes, fileName);
        final StartOssData startOssData = new StartOssData(multipartFile);
        startOssData.setAccessType(accessType);
        startOssData.setOssStorageType(storageType);
        startOssData.setAutoRename(hexName);
        return Result.ok(startOssService.add(startOssData));
    }

    @GetMapping("/**")
    public void getResource(final HttpServletRequest request, HttpServletResponse response) {
        String path = extractPathFromPattern(request);
        if (StringUtils.isEmpty(path))
            throw new StartResourceNotFoundException("资源不存在：" + "/start/resource/" + path);
        byte[] file = startOssService.getPath(path);
        int indexOf = path.lastIndexOf("/");
        response.setContentType("application/*");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(path.substring(indexOf + 1).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
        try {
            IoUtil.write(response.getOutputStream(), true, file);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 把指定URL后的字符串全部截断当成参数
     * 这么做是为了防止URL中包含中文或者特殊字符（/等）时，匹配不了的问题
     *
     * @param request
     * @return;
     */
    private static String extractPathFromPattern(final HttpServletRequest request) {
        String path = "/" + SpringContextTools.getContextPath() + "/" + request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        return path.replaceAll("/{2,}", "/");
    }

}
